using System;
using NUnit.Framework;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace ProgrammingLanguageNr1
{
	[TestFixture()]
	public class SprakProgram_TEST
	{
		[Test()]
		public void HelloWorld ()
		{
			StringReader programString = new StringReader("print(\"Hello World!\")");
			
			SprakProgram program = new SprakProgram(programString);
			program.run();
			
			Assert.AreEqual("Hello World!", program.getOutput()[0]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void MathProblem ()
		{
			StringReader programString = new StringReader("print(5 * 2 + 3 * 4)");
			
			SprakProgram program = new SprakProgram(programString);
			program.run();
			
			Assert.AreEqual("22", program.getOutput()[0]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void SimpleConditional ()
		{
			TextReader programString = File.OpenText("code36.txt");
			
			SprakProgram program = new SprakProgram(programString);
			program.run();
			
			Assert.AreEqual("2", program.getOutput()[0]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void PrintingMathExpressions ()
		{
			TextReader programString = File.OpenText("code19.txt");
			
			SprakProgram program = new SprakProgram(programString);
			program.run();
			
			Assert.AreEqual("20", program.getOutput()[0]);
			Assert.AreEqual("-4", program.getOutput()[1]);
			Assert.AreEqual("11", program.getOutput()[2]);
			Assert.AreEqual("-20", program.getOutput()[3]);
			Assert.AreEqual("-1", program.getOutput()[4]);
			Assert.AreEqual("0.5", program.getOutput()[5]);
			Assert.AreEqual("-0.5", program.getOutput()[6]);
			Assert.AreEqual("100.1", program.getOutput()[7]);
			
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void SingleVariableAssignment ()
		{
			TextReader programString = File.OpenText("code20.txt");
			SprakProgram program = new SprakProgram(programString);
			program.run();
			Assert.AreEqual("5", program.getOutput()[0]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
			
		[Test()]
		public void SimpleVariableUsage ()
		{
			TextReader programString = File.OpenText("code21.txt");
			
			SprakProgram program = new SprakProgram(programString);
			program.run();
			
			Assert.AreEqual("10", program.getOutput()[0]);
			Assert.AreEqual("20", program.getOutput()[1]);
			Assert.AreEqual("30", program.getOutput()[2]);
			Assert.AreEqual("40", program.getOutput()[3]);
			
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void ConditionalProgramFlow ()
		{
			TextReader programString = File.OpenText("code22.txt");
			SprakProgram program = new SprakProgram(programString);
			program.run();
			program.printOutputToConsole();
			
			Assert.AreEqual("blå", program.getOutput()[0]);
			Assert.AreEqual("lila", program.getOutput()[1]);
			Assert.AreEqual("gul", program.getOutput()[2]);
			Assert.AreEqual("orange", program.getOutput()[3]);
			
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void NegativeNumbersInExpression ()
		{
			TextReader programString = File.OpenText("code23.txt");
			SprakProgram program = new SprakProgram(programString);
			program.run();
			
			Assert.AreEqual("-13.5", program.getOutput()[0]);
			Assert.AreEqual("-6", program.getOutput()[1]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
	
		[Test()]
		public void SimpleFunctionCallInProgram ()
		{
			TextReader programString = File.OpenText("code25.txt");
			SprakProgram program = new SprakProgram(programString);

			program.run();
			program.printOutputToConsole();
			
			Assert.AreEqual("42", program.getOutput()[0]);
			Assert.AreEqual(1, program.getOutput().Count);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void FunctionCallReturningValue ()
		{
			TextReader programString = File.OpenText("code26.txt");
			SprakProgram program = new SprakProgram(programString);
			
			program.run();
			program.printOutputToConsole();
			
			Assert.AreEqual(1, program.getOutput().Count);
			Assert.AreEqual("500", program.getOutput()[0]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void FunctionCallWithParameters ()
		{
			TextReader programString = File.OpenText("code27.txt");
			SprakProgram program = new SprakProgram(programString);
			
			program.run();
			program.printOutputToConsole();
			
			Assert.AreEqual(1, program.getOutput().Count);
			Assert.AreEqual("8", program.getOutput()[0]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void FactorialFunctionImplementedInSprak ()
		{
			TextReader programString = File.OpenText("code28.txt");
			SprakProgram program = new SprakProgram(programString);

			program.run();
			program.printOutputToConsole();
			
			Assert.AreEqual("120", program.getOutput()[0]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
		
		[Test()]
		public void MathFunctions ()
		{
			TextReader programString = File.OpenText("code29.txt");
			SprakProgram program = new SprakProgram(programString);
			
			program.run();
			program.printOutputToConsole();
			
			Assert.AreEqual("5", program.getOutput()[0]);
			Assert.AreEqual("0.25", program.getOutput()[1]);
			Assert.AreEqual("35", program.getOutput()[2]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}	
				
		[Test()]
		public void ChangingVariableValueInSubscope ()
		{
			TextReader programString = File.OpenText("code24.txt");
			SprakProgram program = new SprakProgram(programString);
			program.run();
			program.getErrorHandler().printErrorsToConsole();
			program.printOutputToConsole();
			
			Assert.AreEqual("10", program.getOutput()[0]);
			Assert.AreEqual("20", program.getOutput()[1]);
			Assert.AreEqual("0", program.getOutput()[2]);
			Assert.AreEqual(0, program.getErrorHandler().getErrors().Count);
		}
	
	}
}

